package com.fdy.code;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import com.fdy.code.entity.BasisInfo;
import com.fdy.code.entity.ConfigObj;
import com.fdy.code.entity.TableComment;
import com.fdy.code.util.MySqlToJavaUtil;
import com.fdy.code.constant.Constant;
import com.fdy.code.util.EntityInfoUtil;
import com.fdy.code.util.Generator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Document;

import javax.xml.xpath.XPathConstants;
import java.io.File;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * @author fangdy
 * @date 2023-01-06 17:42
 */
public class GeneratorMain {
    private static final Logger logger = LogManager.getLogger(GeneratorMain.class);

    public static void main(String[] args) {
        // 读取配置文件
        ConfigObj configObj = getConfigObj();
        logger.info("配置的信息{}", configObj);
        // 获取库中的表名称
        List<TableComment> list = EntityInfoUtil.getTable(configObj, "");
        for (TableComment tableComment : list) {
            // 创建文件
            createTables(tableComment, configObj);
        }
    }

    /**
     * 读取配置文件 将配置写入到对象中去
     *
     * @return
     */
    private static ConfigObj getConfigObj() {
        InputStream stream = ResourceUtil.getStream("project-config.xml");
        Document document = XmlUtil.readXML(stream);
        String isSwagger = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/isSwagger", document, XPathConstants.STRING));
        String templateType = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/templateType", document, XPathConstants.STRING));
        String templateDir = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/templateDir", document, XPathConstants.STRING));
        String projectName = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/projectName", document, XPathConstants.STRING));
        String version = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/version", document, XPathConstants.STRING));
        String author = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/author", document, XPathConstants.STRING));
        String commonPrefix = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/commonPrefix", document, XPathConstants.STRING));
        String entityPrefix = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/entityPrefix", document, XPathConstants.STRING));
        String daoUrlPrefix = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/daoUrlPrefix", document, XPathConstants.STRING));
        String daoXmlUrl = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/daoXml", document, XPathConstants.STRING));
        String serviceUrlPrefix = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/serviceUrlPrefix", document, XPathConstants.STRING));
        String serviceImplUrlPrefix = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/serviceImplUrlPrefix", document, XPathConstants.STRING));
        String controllerUrlPrefix = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/controllerUrlPrefix", document, XPathConstants.STRING));
        String url = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/url", document, XPathConstants.STRING));
        String port = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/port", document, XPathConstants.STRING));
        String username = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/name", document, XPathConstants.STRING));
        String password = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/password", document, XPathConstants.STRING));
        String database = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/database", document, XPathConstants.STRING));
        String fileOutDir = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/fileOutDir", document, XPathConstants.STRING));
        String customTableName = StrUtil.toStringOrNull(XmlUtil.getByXPath("//project/customTableName", document, XPathConstants.STRING));
        String mysqlUrl = "jdbc:mysql://" + url + ":" + port + "/" + database + "?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8";
        // 创建配置对象 设置相关参数
        return ConfigObj.builder()
                .isSwagger(isSwagger)
                .templateType(templateType)
                .templateDir(templateDir)
                .projectName(projectName)
                .version(version)
                .author(author)
                .templateType(templateType)
                .commonPrefix(commonPrefix)
                .entityPath(commonPrefix + Constant.COMMON_SPILT + entityPrefix)
                .daoPath(commonPrefix + Constant.COMMON_SPILT + daoUrlPrefix)
                .daoXmlPath(commonPrefix + Constant.COMMON_SPILT + daoXmlUrl)
                .servicePath(commonPrefix + Constant.COMMON_SPILT + serviceUrlPrefix)
                .serviceImplPath(commonPrefix + Constant.COMMON_SPILT + serviceImplUrlPrefix)
                .controllerPath(commonPrefix + Constant.COMMON_SPILT +controllerUrlPrefix)
                .dbUrl(mysqlUrl)
                .dbName(username)
                .dbPassword(password)
                .database(database)
                .fileOutDir(fileOutDir)
                .customTableName(customTableName)
                .build();
    }



    public static void createTables(TableComment tableComment, ConfigObj configObj) {

        BasisInfo bi = BasisInfo.builder()
                .configObj(configObj)
                .pkgs(new HashSet<>())
                .table(tableComment.getTableCode())
                .entityName(MySqlToJavaUtil.getClassName(tableComment.getTableCode()))
                .tableRemark(tableComment.getTableRemark())
                .createTime(DateUtil.formatDate(new Date()))
                .project(configObj.getProjectName())
                .version(configObj.getVersion())
                .author(configObj.getAuthor())
                .isSwagger("true")
                .build();
        try {
            // 完善其他信息
            bi = EntityInfoUtil.getInfo(bi);
            // 判断生成文件存放位置格式是否正确
            String fileUrl = configObj.getFileOutDir();
            if (judgeFileOutDir(fileUrl)){
                logger.info("配置的输入目录不正确,配置样例：D:\\com\\");
                return;
            }
            //开始生成文件
            String entity = Generator.createEntity(fileUrl, bi);
            String dao = Generator.createDao(fileUrl, bi).toString();
            // 创建xml
            String daoImpl = Generator.createDaoImpl(fileUrl, bi).toString();
            String service = Generator.createService(fileUrl, bi).toString();
            String serviceImpl = Generator.createServiceImpl(fileUrl, bi).toString();
            String controller = Generator.createController(fileUrl, bi).toString();
            // 是否创建swagger配置文件
//            String swagger = Generator.createSwaggerConfig(fileUrl, bi).toString();
        } catch (SQLException e) {
            logger.info("异常",e);
        }
    }

    private static boolean judgeFileOutDir(String fileUrl) {
        if (StrUtil.isNotEmpty(fileUrl)){
            String separator = File.separator;
            return !fileUrl.endsWith(separator);
        }
        return false;
    }

}
